/**
 * 项目状态服务
 * 状态机实现
 * 按照研发流程设计指引和状态机文档实现
 */

// 使用统一配置入口导入所需模块
const { cloudHelper } = require('../config/project_helpers_config');
const { statusHelper } = require('../config/project_helpers_config');
const { dateHelper } = require('../config/project_helpers_config');
const { dayjs } = require('../config/libs_config');

// 状态定义常量 - 与模型保持一致
const PROJECT_STATUS = {
  DRAFT: 0,        // 草稿
  PENDING: 1,      // 待立项
  APPROVED: 2,     // 已立项
  DESIGNING: 3,    // 设计中
  DEVELOPING: 4,   // 开发中
  TESTING: 5,      // 测试中
  COMPLETED: 6,    // 已完成
  CANCELED: 99     // 已取消
};

/**
 * 项目状态服务类
 * 处理项目状态相关的业务逻辑
 */
const projectStateService = {
  /**
   * 验证状态转换是否合法
   * @param {Object} currentStatus 当前状态对象 {level1, level2, level3, level4}
   * @param {Object} targetStatus 目标状态对象 {level1, level2, level3, level4}
   * @returns {Object} 验证结果 {valid: boolean, reason: string, event: string}
   */
  validateStateTransition: async function(currentStatus, targetStatus) {
    try {
      // 使用statusHelper验证状态转换是否合法
      const result = statusHelper.canTransition(currentStatus, targetStatus);
      
      return {
        valid: result.canTransition,
        reason: result.reason || '状态转换成功',
        event: result.event || 'unknown'
      };
    } catch (error) {
      console.error('[项目状态服务] 验证状态转换出错:', error);
      return {
        valid: false,
        reason: '验证状态转换时出错: ' + error.message,
        event: null
      };
    }
  },
  
  /**
   * 执行状态转换
   * @param {String} projectId 项目ID
   * @param {Object} currentStatus 当前状态对象
   * @param {Object} targetStatus 目标状态对象
   * @param {Object} options 附加选项
   * @param {String} options.reason 状态转换原因
   * @param {Array} options.attachments 关联附件
   * @param {String} options.eventType 事件类型
   * @returns {Promise<Object>} 执行结果
   */
  executeStateTransition: async function(projectId, currentStatus, targetStatus, options = {}) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      if (!currentStatus || !targetStatus) {
        throw new Error('当前状态或目标状态不能为空');
      }
      
      // 验证状态转换是否合法
      const validationResult = await this.validateStateTransition(currentStatus, targetStatus);
      
      if (!validationResult.valid) {
        throw new Error(validationResult.reason);
      }
      
      // 构造API调用参数
      const params = {
        projectId,
        fromState: currentStatus,
        toState: targetStatus,
        reason: options.reason || '',
        attachments: options.attachments || [],
        eventType: options.eventType || validationResult.event || 'manual_transition'
      };
      
      // 调用云函数
      const result = await cloudHelper.callCloudData('plm/transition_project_state', params);
      
      return result;
    } catch (error) {
      console.error('[项目状态服务] 执行状态转换出错:', error);
      throw error;
    }
  },
  
  /**
   * 获取状态历史记录
   * @param {String} projectId 项目ID
   * @param {Object} options 查询选项
   * @param {String} options.branchId 分支ID
   * @param {String} options.eventType 事件类型
   * @param {Number} options.page 页码
   * @param {Number} options.size 每页记录数
   * @returns {Promise<Object>} 历史记录结果
   */
  getStateHistory: async function(projectId, options = {}) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      // 构造API调用参数
      const params = {
        projectId,
        page: options.page || 1,
        size: options.size || 10,
        ...options
      };
      
      // 调用云函数
      const result = await cloudHelper.callCloudData('plm/project_state_history', params);
      
      // 处理结果
      if (result && result.list && Array.isArray(result.list)) {
        result.list = result.list.map(record => ({
          ...record,
          createdTimeFormatted: dateHelper.timestampToDate(record.createdTime),
          fromStateText: statusHelper.getFullStatusDesc(record.fromState),
          toStateText: statusHelper.getFullStatusDesc(record.toState)
        }));
      }
      
      return result;
    } catch (error) {
      console.error('[项目状态服务] 获取状态历史记录出错:', error);
      throw error;
    }
  },
  
  /**
   * 获取当前状态下可用的事件
   * @param {Object} project 项目对象
   * @param {String} role 当前用户角色
   * @returns {Promise<Array>} 可用事件列表
   */
  getAvailableEvents: async function(project, role) {
    try {
      if (!project) {
        throw new Error('项目对象不能为空');
      }
      
      // 构造API调用参数
      const params = {
        projectId: project._id,
        level1: project.level1,
        level2: project.level2,
        level3: project.level3 || '',
        level4: project.level4 || '',
        role: role
      };
      
      // 调用云函数
      const result = await cloudHelper.callCloudData('plm/available_state_events', params);
      
      return result.events || [];
    } catch (error) {
      console.error('[项目状态服务] 获取可用事件出错:', error);
      throw error;
    }
  },
  
  /**
   * 获取项目完成度
   * @param {Object} project 项目对象
   * @returns {Number} 完成度百分比
   */
  getCompletionPercentage: function(project) {
    if (!project) return 0;
    
    // 如果项目已有完成度数据，直接返回
    if (project.completionPercentage !== undefined && project.completionPercentage !== null) {
      return project.completionPercentage;
    }
    
    // 使用状态辅助函数获取估算的完成度
    return statusHelper.getCompletionPercentage(project);
  },
  
  /**
   * 更新项目完成度
   * @param {String} projectId 项目ID
   * @param {Number} percentage 完成度百分比
   * @returns {Promise<Object>} 更新结果
   */
  updateCompletionPercentage: async function(projectId, percentage) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      if (percentage < 0 || percentage > 100) {
        throw new Error('完成度百分比必须在0-100之间');
      }
      
      // 构造API调用参数
      const params = {
        projectId,
        completionPercentage: percentage
      };
      
      // 调用云函数
      const result = await cloudHelper.callCloudData('plm/update_completion', params);
      
      return result;
    } catch (error) {
      console.error('[项目状态服务] 更新项目完成度出错:', error);
      throw error;
    }
  },
  
  /**
   * 创建状态流转图谱数据
   * @param {String} projectId 项目ID
   * @returns {Promise<Object>} 图谱数据
   */
  createStateGraph: async function(projectId) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      // 获取项目状态历史
      const history = await this.getStateHistory(projectId, { size: 100 });
      
      // 构建状态转换图谱
      const nodes = [];
      const edges = [];
      
      // 添加节点
      if (history && history.list) {
        const addedNodes = new Set(); // 用于跟踪已添加的节点
        
        history.list.forEach((record, index) => {
          // 添加起始状态节点
          const fromStateKey = `${record.fromLevel1}-${record.fromLevel2 || 'none'}-${record.fromLevel3 || 'none'}-${record.fromLevel4 || 'none'}`;
          
          if (!addedNodes.has(fromStateKey)) {
            nodes.push({
              id: fromStateKey,
              label: statusHelper.getFullStatusDesc(record.fromState),
              group: record.fromLevel1,
              timestamp: record.createdTime,
              formattedTime: dateHelper.timestampToDate(record.createdTime),
              isInitial: index === history.list.length - 1, // 第一条记录是初始状态
              isFinal: false
            });
            
            addedNodes.add(fromStateKey);
          }
          
          // 添加目标状态节点
          const toStateKey = `${record.toLevel1}-${record.toLevel2 || 'none'}-${record.toLevel3 || 'none'}-${record.toLevel4 || 'none'}`;
          
          if (!addedNodes.has(toStateKey)) {
            nodes.push({
              id: toStateKey,
              label: statusHelper.getFullStatusDesc(record.toState),
              group: record.toLevel1,
              timestamp: record.createdTime,
              formattedTime: dateHelper.timestampToDate(record.createdTime),
              isInitial: false,
              isFinal: index === 0 // 最后一条记录的目标状态是最终状态
            });
            
            addedNodes.add(toStateKey);
          }
          
          // 添加边
          edges.push({
            from: fromStateKey,
            to: toStateKey,
            label: record.eventType || '状态转换',
            timestamp: record.createdTime,
            formattedTime: dateHelper.timestampToDate(record.createdTime),
            comment: record.comment || '',
            operator: record.createdByName || ''
          });
        });
      }
      
      return { nodes, edges };
    } catch (error) {
      console.error('[项目状态服务] 创建状态流转图谱出错:', error);
      throw error;
    }
  },
  
  /**
   * 执行状态流转
   * @param {Object} transitionData 流转数据
   * @param {String} transitionData.projectId 项目ID
   * @param {String} transitionData.branchId 分支ID
   * @param {Object} transitionData.fromState 源状态
   * @param {Object} transitionData.toState 目标状态
   * @param {String} transitionData.eventType 事件类型
   * @param {String} transitionData.comment 流转说明
   * @returns {Promise<Object>} 流转结果
   */
  transitionState: async function(transitionData) {
    try {
      if (!transitionData.projectId || !transitionData.branchId) {
        throw new Error('项目ID和分支ID不能为空');
      }
      
      // 1. 验证状态流转是否有效
      const isValid = statusHelper.isValidStateTransition(
        transitionData.fromState, 
        transitionData.toState
      );
      
      if (!isValid) {
        throw new Error('状态流转无效，请检查源状态和目标状态');
      }
      
      // 2. 调用云函数执行状态流转
      const result = await cloudHelper.callCloudData('plm/transition_state', transitionData);
      
      return result;
    } catch (error) {
      console.error('[项目状态服务] 状态流转失败:', error);
      throw error;
    }
  },
  
  /**
   * 获取可用的状态流转操作
   * @param {String} projectId 项目ID
   * @param {String} branchId 分支ID
   * @returns {Promise<Array>} 可用操作列表
   */
  getAvailableTransitions: async function(projectId, branchId) {
    try {
      if (!projectId || !branchId) {
        throw new Error('项目ID和分支ID不能为空');
      }
      
      // 调用云函数获取可用流转操作
      const result = await cloudHelper.callCloudData('plm/available_transitions', {
        projectId,
        branchId
      });
      
      return result.list || [];
    } catch (error) {
      console.error('[项目状态服务] 获取可用状态流转操作失败:', error);
      return [];
    }
  },
  
  /**
   * 获取状态历史记录
   * @param {String} projectId 项目ID
   * @param {String} branchId 分支ID
   * @returns {Promise<Array>} 状态历史记录
   */
  getStateHistory: async function(projectId, branchId) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      // 构建查询参数
      const params = {
        projectId,
      };
      
      // 如果指定了分支ID，只查询特定分支的历史
      if (branchId) {
        params.branchId = branchId;
      }
      
      // 调用云函数获取状态历史
      const result = await cloudHelper.callCloudData('plm/state_history', params);
      
      // 格式化历史记录
      if (result && result.list) {
        return result.list.map(item => this._formatStateHistory(item));
      }
      
      return [];
    } catch (error) {
      console.error('[项目状态服务] 获取状态历史失败:', error);
      return [];
    }
  },
  
  /**
   * 格式化状态历史记录
   * @param {Object} history 历史记录
   * @returns {Object} 格式化后的历史记录
   * @private
   */
  _formatStateHistory: function(history) {
    if (!history) return null;
    const { dayjs } = require('../config/libs_config');
    
    // 格式化状态历史
    const formatted = {
      _id: history._id || '',
      projectId: history.projectId || '',
      branchId: history.branchId || '',
      
      // 源状态和目标状态
      fromState: history.fromState || {},
      toState: history.toState || {},
      
      // 事件信息
      eventType: history.eventType || '',
      comment: history.comment || '',
      createdBy: history.createdBy || '',
      createdByName: history.createdByName || '未知',
      createdTime: history.createdTime || Date.now() / 1000,
      
      // 计算状态描述
      fromStateDesc: statusHelper.getFullStatusDesc(history.fromState || {}),
      toStateDesc: statusHelper.getFullStatusDesc(history.toState || {})
    };
    
    // 格式化时间
    formatted.createdTimeFormatted = formatted.createdTime 
      ? dayjs.unix(formatted.createdTime).format('YYYY-MM-DD HH:mm:ss')
      : '';
    
    return formatted;
  },
  
  /**
   * 判断用户是否有权限执行状态流转
   * @param {Object} currentState 当前项目状态
   * @param {Object} userInfo 用户信息
   * @returns {Object} 权限检查结果 {hasPermission, message}
   */
  checkTransitionPermission: function(currentState, userInfo) {
    if (!currentState || !userInfo) {
      return { hasPermission: false, message: '缺少项目状态或用户信息' };
    }
    
    // 按照状态机规则检查权限
    const level1 = currentState.level1;
    const level2 = currentState.level2;
    const role = userInfo.role || '';
    
    // 董事长可以操作所有状态
    if (role === 'director') {
      return { hasPermission: true, message: '董事长具有全部权限' };
    }
    
    // 项目审核阶段权限检查
    if (level1 === 1) {
      // 研发经理可以在"研发经理"子状态和"分配"子状态操作
      if (role === 'manager' && (level2 === 'manager' || level2 === 'assign')) {
        return { hasPermission: true, message: '研发经理具有操作权限' };
      }
      
      // 其他情况无权限
      return { 
        hasPermission: false, 
        message: `在项目审核-${statusHelper.getLevel2StatusName(level1, level2)}阶段，需要${level2 === 'director' ? '董事长' : '研发经理'}权限` 
      };
    }
    
    // 硬件设计阶段权限检查
    if (level1 === 2) {
      // 硬件工程师可以在设计阶段操作
      if (role === 'hardware' && level2 === 'design') {
        return { hasPermission: true, message: '硬件工程师具有操作权限' };
      }
      
      // 研发经理可以在审核子状态操作
      if (role === 'manager' && level2 === 'review') {
        return { hasPermission: true, message: '研发经理具有操作权限' };
      }
      
      // 采购人员可以在打样子状态操作
      if (role === 'purchase' && level2 === 'proto') {
        return { hasPermission: true, message: '采购人员具有操作权限' };
      }
      
      // 样品组可以在制样和在库子状态操作
      if (role === 'sample' && (level2 === 'sample' || level2 === 'stock')) {
        return { hasPermission: true, message: '样品组具有操作权限' };
      }
      
      // 其他情况无权限
      return { 
        hasPermission: false, 
        message: `在硬件设计-${statusHelper.getLevel2StatusName(level1, level2)}阶段，需要特定权限` 
      };
    }
    
    // 各种状态机对应的权限检查...
    // [省略其他阶段权限检查，实际应该按照状态机逻辑完整实现]
    
    // 默认无权限
    return { hasPermission: false, message: '无操作权限' };
  },
  
  /**
   * 检查状态流转的前置条件
   * @param {Object} transitionData 流转数据
   * @returns {Promise<Object>} 检查结果 {success, message}
   */
  checkTransitionPreconditions: async function(transitionData) {
    try {
      if (!transitionData.projectId || !transitionData.branchId) {
        return { success: false, message: '项目ID和分支ID不能为空' };
      }
      
      // 调用云函数检查前置条件
      const result = await cloudHelper.callCloudData('plm/check_transition_preconditions', transitionData);
      
      return {
        success: result.code === 0,
        message: result.message || '检查完成'
      };
    } catch (error) {
      console.error('[项目状态服务] 检查状态流转前置条件失败:', error);
      return { success: false, message: error.message || '检查状态流转前置条件失败' };
    }
  },
  
  /**
   * 获取项目完成度
   * @param {String} projectId 项目ID
   * @param {String} branchId 分支ID
   * @returns {Promise<number>} 完成度(0-100)
   */
  getCompletionPercentage: async function(projectId, branchId) {
    try {
      if (!projectId) {
        throw new Error('项目ID不能为空');
      }
      
      // 构造查询参数
      const params = { projectId };
      if (branchId) {
        params.branchId = branchId;
      }
      
      // 调用云函数获取完成度
      const result = await cloudHelper.callCloudData('plm/completion_percentage', params);
      
      return result.data?.percentage || 0;
    } catch (error) {
      console.error('[项目状态服务] 获取项目完成度失败:', error);
      return 0;
    }
  },
};

// 导出项目状态服务
module.exports = projectStateService; 